package com.xy6.model.bean.wrapper;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.xy6.model.api.bean.MyStatusWrapper;
import com.xy6.model.api.vo.MyJob;
import com.xy6.model.utils.MyTaskUtils;

/**
 * job的包装类，包含job的全部信息，后续执行时，无需再查询基本信息。
 * 装饰器模式。
 * 
 * @author zhang
 * @since 2018-05-12
 */
public class MyJobWrapper {

	private MyJob job;
	
	private List<MyTaskWrapper> tasks;
	
	private MyStatusWrapper status;
	
	/** <id,task> */
	private Map<String, MyTaskWrapper> mapTasks = new HashMap<>(10);
	
	/** task01,task02 */
	private List<String> lines;
	
	/** first task id */
	private String first;
	
	/** task的后继task。用于执行完一个task后，执行后续的task */
	private Map<String, List<String>> nextTasks = new HashMap<>(10);
	
	/** task的前趋task。用于执行一个task前，检查依赖的task是否都已执行完毕 */
	private Map<String, List<String>> preTasks = new HashMap<>(10);

	public MyJobWrapper(MyJob job){
		this.job = job;
		this.tasks = MyTaskUtils.findTasks(job.getTaskIds());
		for(MyTaskWrapper elem : tasks){
			mapTasks.put(elem.getId(), elem);
		}
		// DAG的边
		lines = Arrays.asList(this.job.getLines().split(";"));
		initFirst();
		initRelation();
	}
	
	public MyJob getJob() {
		return job;
	}

	public List<MyTaskWrapper> getTasks() {
		return tasks;
	}

	public void setTasks(List<MyTaskWrapper> tasks) {
		this.tasks = tasks;
	}

	public String getId() {
		return this.job.getId();
	}

	public String getCron() {
		return this.job.getCron();
	}
	
	public List<String> getLines() {
		return lines;
	}

	public MyStatusWrapper getStatus() {
		return status;
	}

	public void setStatus(MyStatusWrapper status) {
		this.status = status;
	}

	public Map<String, MyTaskWrapper> getMapTasks(){
		return mapTasks;
	}
	
	public MyTaskWrapper getFirst() {
		return mapTasks.get(first);
	}

	public Map<String, List<String>> getNextTasks() {
		return nextTasks;
	}

	public Map<String, List<String>> getPreTasks() {
		return preTasks;
	}

	/**
	 * 查找DAG图的第一个顶点
	 */
	private void initFirst(){
		Set<String> endV = new HashSet<>(10);
		for(String line : lines){
			endV.add(line.split(",")[1]);
		}
		List<String> vertex = Arrays.asList(job.getTaskIds().split(","));
		for(String elem : vertex){
			if(!endV.contains(elem)){
				first = elem;
				break;
			}
		}
		endV = null;
		vertex = null;
	}
	
	/**
	 * 初始化task的前趋、后继task，保存起来
	 */
	private void initRelation(){
		String[] lines = job.getLines().split(";");
		for(String line : lines){
			String[] v = line.split(",");
			// task后续的task
			if(!nextTasks.containsKey(v[0])){
				nextTasks.put(v[0], new ArrayList<String>(5));
			}
			nextTasks.get(v[0]).add(v[1]);
			// 依赖的task
			if(!preTasks.containsKey(v[1])){
				preTasks.put(v[1], new ArrayList<String>(5));
			}
			preTasks.get(v[1]).add(v[0]);
		}
		// 遍历顶点，如果没有前驱、后继，也将其添加到集合中，避免客户端判空
		for(MyTaskWrapper elem : tasks){
			if(!preTasks.containsKey(elem.getId())){
				preTasks.put(elem.getId(), new ArrayList<String>(0));
			}
			if(!nextTasks.containsKey(elem.getId())){
				nextTasks.put(elem.getId(), new ArrayList<String>(0));
			}
		}
	}
	
	@Override
	public String toString() {
		return "MyJobInfo [job=" + job + ", tasks=" + tasks + ", status=" + status + "]";
	}

}
